
#include <cassert>
#include <iostream>
#include <mpi.h>
#include <vector>
using namespace std;

int main(int argc, char **argv) {
  int my_rank, num_proc;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &num_proc);

  vector<int> send_vec1{1, 2, 3, 4, 5}, send_vec2{6, 7, 8, 9, 10, 11};
  vector<int> recv_vec1(send_vec1.size()), recv_vec2(send_vec2.size());
  vector<int> exclude_rank = {0};

  MPI_Group world_group, rem_group;
  MPI_Comm slave_comm, new_comm, split_comm;

  MPI_Comm_group(MPI_COMM_WORLD, &world_group);

  MPI_Group_excl(world_group, exclude_rank.size(), exclude_rank.data(),
                 &rem_group);

  MPI_Comm_create(MPI_COMM_WORLD, rem_group, &new_comm);

  int color = my_rank % 2;

  MPI_Comm_split(MPI_COMM_WORLD, color, my_rank, &split_comm);

  //   if (my_rank != 0) {
  //   }

  int rank_sum;
  MPI_Allreduce(&my_rank, &rank_sum, 1, MPI_INT, MPI_SUM, split_comm);

  //   cout << "mpi_comm_world rank = " << my_rank << "  rank sum = " <<
  //   rank_sum
  //        << endl;
  //   cout << endl;

  int split_comm_rank;
  MPI_Comm_rank(split_comm, &split_comm_rank);
  //   cout << "split comm rank = " << split_comm_rank
  //        << "  mpi_comm_world rank = " << my_rank << endl;
  //   cout << endl;

  int group_rank;
  MPI_Group_rank(rem_group, &group_rank);
  //   if (group_rank != MPI_UNDEFINED) {
  //     cout << "rem_group rank = " << group_rank
  //          << "  mpi_comm_world rank = " << my_rank << endl;
  //   }
  //   cout << endl;

  // 没有包含 0 进程又会如何
  // 不加这个条件会报错
  if (my_rank != 0) {
    MPI_Allreduce(&my_rank, &rank_sum, 1, MPI_INT, MPI_SUM, new_comm);
    cout << "mpi_comm_world rank = " << my_rank << "  rank sum = " << rank_sum
         << endl;
  }
  
  MPI_Group_free(&world_group);
  // group 倒没有下面这个问题
  MPI_Group_free(&rem_group);
  // 不加这个判断条件会报错
  if (my_rank != 0)
    MPI_Comm_free(&new_comm);
  MPI_Comm_free(&split_comm);
  MPI_Finalize();

  return 0;
}